#include <iostream>
#include <thread>
#include <string>
#include <unistd.h>
#include <vector>

using namespace std;

//1.析构时触发terminate
void TimeTask()
{
    for(int i=0;i<10000;++i)
        std::cout<<i<<":"<<" thread"<<std::endl;
}

//2.仿函数细节
// class TodoTask
// {
// public:
//     void operator()() const
//     {
//         std::cout<<10<<std::endl;
//     }
//     // void operator()(int num) const
//     // {
//     //     std::cout<<10<<std::endl;
//     // }
// };

//4.参数问题
// void func(int i,std::string const& s)
// {
//     std::cout<<i<<":"<<s<<std::endl;
// }
// void oops()
// {
//     char buffer[1024] = "hello world";
//     //std::thread t4(func,10,buffer);
//     std::thread t4(func,10,std::string(buffer));
//     t4.detach();
// }
// void func1(int i,int& data)
// {
//     data+=i;
// }
// void oops_again1()
// {
//     int data = 10;
//     //std::thread t4(func1,10,data);
//     std::thread t4(func1,10,std::ref(data));
//     t4.join();
//     std::cout<<data<<std::endl;
// }
// void oops_again2(int data)
// {
//     std::thread t4(func1,10,data);
//     t4.join();
//     std::cout<<data<<std::endl;
// }
// void oops_again3(int& data)
// {
//     std::thread t4(func1,10,data);
//     t4.join();
//     std::cout<<data<<std::endl;
// }

//5.异常与退出
//5.1.try catch过于麻烦
// int nozero(int num)
// {
//     if(num==0) throw "Division by zero condition!";
//     return 10/num;
// }
// void catch_exception()
// {
//     std::thread t([](){
//         std::cout<<10<<std::endl;
//     });
//     try
//     {
//         nozero(0);
//     }
//     catch(const char* msg)
//     {
//         t.join();
//         std::cout<<"catch to join"<<std::endl;
//         std::cerr << msg << std::endl;
//     }
//     t.join();
//     std::cout<<"success"<<std::endl;
// }
//5.2守卫类释放线程
// class thread_guard
// {
// private:
//     std::thread& _t;
// public:
//     explicit thread_guard(std::thread& t):_t(t){};
//     ~thread_guard()
//     {
//         //走到销毁逻辑后发现没有被join掉
//         if(_t.joinable())
//             _t.join();
//     }
//     thread_guard(thread_guard& th) = delete;
//     thread_guard& operator=(thread_guard& th) = delete;
// };

//6.thread_guard管理thread&的正常join退出
// class thread_guard
// {
// private:
//     std::thread& t;
// public:
//     explicit thread_guard(std::thread& _t)
//     :t(_t)
//     {}
//     ~thread_guard()
//     {
//         if(t.joinable())
//             t.join();
//     }
//     thread_guard(const thread_guard& _t) = delete;
//     thread_guard& operator=(const thread_guard& _t) = delete;
// };

//7.thread所属权
// void ownership_func()
// {
//     cout<<this_thread::get_id()<<endl;
// }
// void other_ownership_func()
// {
//     cout<<this_thread::get_id()<<endl;
// }

//8.scoped_thread管理thread正常join退出
// class scoped_thread
// {
// private:
//     thread t;
// public:
//     explicit scoped_thread(thread _t)
//     :t(std::move(_t))
//     {
//         if(!t.joinable())
//             throw std::logic_error("No thread");
//     }
//     ~scoped_thread()
//     {
//         t.join();
//     }
//     scoped_thread(const scoped_thread& _t)=delete;
//     scoped_thread&operator=(const scoped_thread& _t)=delete;
// };

//9.joining_thread构造thread并且管理
// class MY_joining_thread //仿照thread的源代码实现,传给内部生成的都是右值副本
// {
// private:
//     std::thread t;
// public:
//     MY_joining_thread()noexcept = default;
//     template<class Callable,class ...Args>
//     explicit MY_joining_thread(Callable&& func,Args&& ...args)
//     :t(std::forward<Callable>func,std::forward<Args>(arg)...)
//     {}
//     explicit MY_joining_thread(std::thread _t) noexcept
//     :t(std::move(_t))
//     {}
//     MY_joining_thread(MY_joining_thread&& other) noexcept
//     :t(std::move(other.t))
//     {}
//     MY_joining_thread& operator=(MY_joining_thread&& other) noexcept
//     {
//         if(t.get_id()==other.t.get_id())
//             return *this;
//         if(joinable()) t.join();
//         t=move(other.t);
//         return *this;
//     }
//     MY_joining_thread& operator=(std::thread _t) noexcept
//     {
//         if(t.get_id()==_t.get_id())
//             return *this;
//         if(joinable()) t.join();
//         t=move(_t);
//         return *this;
//     }
//     ~MY_joining_thread() noexcept
//     {
//         if(joinable()) t.join();
//     }
//     bool joinable() const noexcept
//     {
//         return t.joinable();
//     }
// };

//11.真实线程数
// template<class Iterator,class T>
// struct accumylate_block
// {
//     void operator()(Iterator begin,Iterator end,T& target)
//     {
//         target=std::accumulate(begin.end,target);
//     }
// };
// template<class Iterator,class T>
// T parallel_accumulate(Iterator begin,Iterator end,T target)
// {
//     const unsigned long length = std::distance(begin.end);
//     if(length==0) return target;
//     const unsigned int thread_nums = std::min(std::thread::hardware_concurrency()==0?
//                                         2:min(std::thread::hardware_concurrency(),length));
//     const unsigned int block_size = length/thread_nums;
//     vector<T> results(thread_nums);
//     vector<thread> threads(thread_nums-1); //有一个主线程
//     Iterator start = begin;
//     for(int i=0;i<thread_nums;++i)
//     {
//         Iterator final = begin;
//         std::advance(final,block_size);
//         threadsp[i]=std::thread(accumylate_block(),start,final,std::ref(results[i]));
//         start=final;
//     }
//     accumylate_block()(start,end,results[thread_nums-1]);
//     for(auto& e:threads)
//         e.join();
//     return std::accumulate(results.begin().results.end(),target);
// }

int main()
{
    //1.析构时触发terminate
    // {
        std::thread t1(TimeTask);
        t1.join();
        //t1.detach();
    // }

    //2.仿函数细节
    // {
    //     TodoTask t;
    //     std::thread t2(t,10);
    //     std::thread t2_1(TodoTask());
    //     std::thread t2_1(TodoTask(),100);
    //     t2_1.join();
    //     std::thread t2_2((TodoTask()));
    //     t2_2.join();
    //     std::thread t2_3{TodoTask()};
    //     t2_3.join();
    // }

    //3.lambda
    // {
    //     std::thread t3([](int num){
    //         for(int i=0;i<num;i++)
    //             std::cout<<i<<std::endl;
    //     },10);
    // }
    
    //4.参数问题
    // oops();
    // sleep(3);
    //oops_again1();
    //oops_again2(10);
    //int data = 10;
    //oops_again3(data);

    //5.异常与退出
    //catch_exception();

    //6.thread_guard
    // std::thread t([](){
    //     std::cout<<"running..."<<std::endl;
    // });
    // thread_guard g(t);

    //7.thread所属权
    // thread t1(ownership_func);
    // thread t2(std::move(t1));
    // t2.join();
    // //错误
    // // thread t1(ownership_func);
    // // thread t2(std::move(t1));
    // // t2 = std::thread(other_ownership_func); //原先从t1来的没有join

    //8.scoped_thread
    //scoped_thread st(thread([](){cout<<"hello"<<endl;}));

    //9.joining_thread构造thread并且管理
    // MY_joining_thread jt1([](){cout<<"hello"<<endl;});
    // thread t([](){cout<<"hello"<<endl;});
    // MY_joining_thread jt(std::move(t));

    //10.vector管理thread
    // vector<thread> vt;
    // for(int i=0;i<10;i++)
    // {
    //     vt.emplace_back([](int num)
    //     {
    //         cout<<this_thread::get_id()<<":print "<<num<<endl;
    //     },i);
    // }
    // for(auto& e:vt) e.join();

    //11.识别标志
    //cout<<this_thread::get_id<<endl;
    
    return 0;
}